#ifndef MOCHA_DETAIL_EXPORTED_GRAPHICS_PLUGIN_HPP_INCLUDED
#define MOCHA_DETAIL_EXPORTED_GRAPHICS_PLUGIN_HPP_INCLUDED

/**
 * @file
 */

#include <cstdint>
#include "mocha/exported_object.hpp"
#include "mocha/graphics_plugin.hpp"

namespace mocha { namespace graphics {
/**
 * 
 * @param P 
 * @param I 
 * @see c_graphics_plugin
 * @see graphics_plugin
 */
template<typename P, typename I = c_graphics_plugin>
class exported_graphics_plugin : public exported_object<P, I, c_graphics_plugin, graphics_plugin>, private c_graphics_plugin, public graphics_plugin {
public:
	exported_graphics_plugin() {
		c_graphics_plugin::self = static_cast<c_graphics_plugin*>(this);
		c_graphics_plugin::type_name = &exported_graphics_plugin<P, I>::type_name;
		c_graphics_plugin::capabilities = &exported_graphics_plugin<P, I>::capabilities;
		c_graphics_plugin::open_display_mode = &exported_graphics_plugin<P, I>::open_display_mode;
		c_graphics_plugin::swap_buffers = &exported_graphics_plugin<P, I>::swap_buffers;
		c_graphics_plugin::clear_back_buffer = &exported_graphics_plugin<P, I>::clear_back_buffer;
	}
	virtual ~exported_graphics_plugin() {}
private:
	static const plugin_char_t* type_name(const c_graphics_plugin* object) {
		return MOCHA_DETAIL_CONST_SELF_CALL(P, object, type_name)();
	}
	static std::int32_t capabilities(const c_graphics_plugin* object, graphics_caps* caps) {
		return MOCHA_DETAIL_CONST_SELF_CALL(P, object, capabilities)(*caps);
	}
	static std::int32_t open_display_mode(c_graphics_plugin* object, std::uint32_t width, std::uint32_t height, std::int8_t full) {
		return MOCHA_DETAIL_SELF_CALL(P, object, open_display_mode)(static_cast<size_t>(width), static_cast<size_t>(height), static_cast<bool>(full));
	}
	static std::int32_t swap_buffers(c_graphics_plugin* object) {
		return MOCHA_DETAIL_SELF_CALL(P, object, swap_buffers)();
	}
	static std::int32_t clear_back_buffer(c_graphics_plugin* object, rgba_t cc) {
		return MOCHA_DETAIL_SELF_CALL(P, object, clear_back_buffer)(cc);
	}
};
}}

#endif

